package com.miracle9.game.thread;

import com.miracle9.game.entity.*;
import com.miracle9.game.enums.GameTypeEnums;
import com.miracle9.game.service.*;
import com.miracle9.game.util.MyUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("myTimer")
public class MyTimer
        extends Thread {

    private Logger logger = Logger.getLogger(MyTimer.class);
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserService userService;
    @Autowired
    private NewRegistService newRegistService;
    @Autowired
    private PayLogService payLogService;
    @Autowired
    private ChargeStatisService chargeStatisService;
    @Autowired
    private DailyActiveService dailyActiveService;
    @Autowired
    private DeskResultService deskResultService;
    @Autowired
    private AdminLogService adminLogService;
    @Autowired
    private ComputerOrderService computerOrderService;
    @Autowired
    private UserAwardService userAwardService;
    @Autowired
    private DayAccountsService dayAccountsService;
    @Autowired
    private GameService gameService;
    @Autowired
    private UserMailService userMailService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private UserTopService userTopService;
    @Autowired
    private UserRegistLogService userRegistLogService;

    @PostConstruct
    public void myTimerStart() {
        start();
    }

    public void run() {
        try {
            for (; ; ) {
                Calendar calendar = Calendar.getInstance();
                int hour = calendar.get(Calendar.HOUR_OF_DAY);
                int minute = calendar.get(Calendar.MINUTE);
                if ((hour == 0) && (minute == 0)) {
                    this.logger.info("开始执行凌晨任务");
                    calendar.add(Calendar.DATE, -1);
                    String date = MyUtil.dateFormatYMD_Sting(calendar.getTime());
                    try {
                        ActivityInfo activityInfo = this.activityService.getActivityInfo();
                        if (activityInfo != null) {
                            cleanUserActivityStatus();
                            ranKingProcess();
                        }
                        for (Integer gameType : GameTypeEnums.gameTypes()) {
                            this.gameService.refreshUserTop(gameType, null);
                        }
                        this.systemConfigService.resetTempConfig();
                        addChargeStatis(date);
                        addDailyActive(date);
                        addNewRegist(date);
                        deleteProcess();
                        updateNoActive();
                        cleanPastRegistLog();
                    } catch (Exception e) {
                        this.logger.info("凌晨任务出错，但是不影响账目的生成。");
                    }
                    this.dayAccountsService.createAccounts(date);
                    sleep(82800000L);
                } else {
                    sleep(50000L);
                }
            }
        } catch (Exception e) {
            this.logger.error("", e);
        }
    }

    public void cleanPastRegistLog() {
        Date d = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        if (c.get(5) == 1) {
            c.add(2, -1);
            c.set(5, 1);
            String date = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());

            this.userRegistLogService.cleanPastRegistLog(date);
        }
    }

    public void cleanUserActivityStatus() {
        ActivityInfo activityInfo = this.activityService.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        if (activityInfo.getActivityStatus() == 1) {
            this.activityService.cleanUserActivityStatus();
        }
    }

    public void ranKingProcess() {
        ActivityInfo activityInfo = this.activityService.getActivityInfo();
        if (activityInfo.getActivityStatus() == 1) {
            List<Activity> activityList = new ArrayList();
            activityList = this.activityService.getActivityList(4);
            int nGameType = 0;
            int nActivityId = 0;
            for (int i = 0; i < activityList.size(); i++) {
                nActivityId = ((Activity) activityList.get(i)).getId();
                int nRankType = ((Activity) activityList.get(i)).getCondition1();
                nGameType = ((Activity) activityList.get(i)).getCondition2();
                User user = new User();
                if (nRankType == 0) {
                    this.logger.info("start______________________处理日排行榜");
                    List<UserTop> tops = this.userTopService.topList(nGameType, nRankType);

                    UserTop userTop = new UserTop();
                    for (int j = 0; j < tops.size(); j++) {
                        userTop = (UserTop) tops.get(j);
                        int nUserId = userTop.getUserId();

                        user = this.userService.getUser(nUserId);
                        if (user.getPromoterId() == 0) {
                            if ((i == 0) && (j == 0)) {
                                this.logger.info(j + "：1，" + userTop.toString() +
                                        nUserId + "，" + nActivityId);
                                this.activityService.checkUserTopActivity(nUserId,
                                        nActivityId);
                            } else if ((i == 1) && (j >= 2) && (j <= 3)) {
                                this.logger.info(j + "：2~3，" + userTop.toString() +
                                        nUserId + "，" + nActivityId);
                                this.activityService.checkUserTopActivity(nUserId,
                                        nActivityId);
                            } else if ((i == 2) && (j >= 4) && (j <= 10)) {
                                this.logger.info(j + "：4~10，" + userTop.toString() +
                                        nUserId + "，" + nActivityId);
                                this.activityService.checkUserTopActivity(nUserId,
                                        nActivityId);
                            }
                        }
                    }
                    this.logger.info("end______________________处理日排行榜");
                }
                if (nRankType == 1) {
                    this.logger.info("start______________________处理周排行榜");
                    if (Calendar.getInstance().get(7) == 6) {
                        List<UserTop> tops = this.userTopService.topList(nGameType,
                                nRankType + 1);

                        UserTop userTop = new UserTop();
                        for (int j = 0; j < tops.size(); j++) {
                            userTop = (UserTop) tops.get(j);
                            int nUserId = userTop.getUserId();
                            user = this.userService.getUser(nUserId);
                            if (user.getPromoterId() == 0) {
                                if (j == 0) {
                                    this.activityService.checkUserTopActivity(
                                            nUserId, nActivityId);
                                } else if ((j >= 2) && (j <= 3)) {
                                    this.activityService.checkUserTopActivity(
                                            nUserId, nActivityId);
                                } else if ((j >= 4) && (j <= 10)) {
                                    this.activityService.checkUserTopActivity(
                                            nUserId, nActivityId);
                                }
                            }
                        }
                    } else if (Calendar.getInstance().get(7) != 2) {
                        this.logger.info("不是周五什么都不做");
                    }
                    this.logger.info("end______________________处理周排行榜");
                }
            }
        }
    }

    private void deleteProcess() {
        try {
            Calendar c = Calendar.getInstance();
            c.add(5, -91);
            String date = MyUtil.dateFormatYMD_Sting(c.getTime());
            this.deskResultService.deletePastResult(date);
            this.adminLogService.deletePastAdminLog(date);
            this.userMailService.deletePastMail(date);
            this.noticeService.deletePastNotice(date);
            this.computerOrderService.deletePastOrder(date);
            this.userAwardService.deletePastAward(date);
            this.userService.deleteUserPlayLog(date);
            this.payLogService.deletePastPayLog(date);
        } catch (Exception e) {
            this.logger.error("", e);
        }
    }

    private void addNewRegist(String date) {
        String today = MyUtil.dateFormatYMD_Sting(new Date());
        int[] newRegistCount = this.userService.countNewRegist(date, today);
        NewRegist nr = new NewRegist(newRegistCount[0], date, 0);
        this.newRegistService.addNewRegist(nr);
        nr = new NewRegist(newRegistCount[1], date, 1);
        this.newRegistService.addNewRegist(nr);
        nr = new NewRegist(newRegistCount[0] + newRegistCount[1], date, 2);
        this.newRegistService.addNewRegist(nr);
    }

    private void addDailyActive(String date) {
        String today = MyUtil.dateFormatYMD_Sting(new Date());
        int[] activeCount = this.userService.countDailyActive(date, today);
        DailyActive da = new DailyActive(activeCount[0], date, 0);
        this.dailyActiveService.addDailyActive(da);
        da = new DailyActive(activeCount[1], date, 1);
        this.dailyActiveService.addDailyActive(da);
        da = new DailyActive(activeCount[0] + activeCount[1], date, 2);
        this.dailyActiveService.addDailyActive(da);
    }

    private void addChargeStatis(String date) {
        String today = MyUtil.dateFormatYMD_Sting(new Date());
        List<PayLog> payLogs = this.payLogService.getPayLog(date, today);
        int count = payLogs.size();
        Set<Integer> userIdSet = new HashSet();
        int amount = 0;
        for (PayLog p : payLogs) {
            userIdSet.add(Integer.valueOf(p.getUserId()));
            amount = (int) (amount + p.getMoney());
        }
        int user_count = userIdSet.size();
        int money = 0;
        if (count > 0) {
            money = amount / count;
        }
        int arpu = 0;
        if (user_count > 0) {
            arpu = amount / user_count;
        }
        ChargeStatis cs = new ChargeStatis(amount, arpu, count, date, money,
                user_count, 2);
        this.chargeStatisService.addChargeStatis(cs);

        count = 0;
        userIdSet = new HashSet();
        amount = 0;
        for (PayLog p : payLogs) {
            if (p.getParentPromoterId() == 0) {
                userIdSet.add(Integer.valueOf(p.getUserId()));
                amount = (int) (amount + p.getMoney());
            }
        }
        user_count = userIdSet.size();
        money = 0;
        if (count > 0) {
            money = amount / count;
        }
        arpu = 0;
        if (user_count > 0) {
            arpu = amount / user_count;
        }
        cs = new ChargeStatis(amount, arpu, count, date, money, user_count, 0);
        this.chargeStatisService.addChargeStatis(cs);

        count = 0;
        userIdSet = new HashSet();
        amount = 0;
        for (PayLog p : payLogs) {
            if (p.getParentPromoterId() != 0) {
                userIdSet.add(Integer.valueOf(p.getUserId()));
                amount = (int) (amount + p.getMoney());
            }
        }
        user_count = userIdSet.size();
        money = 0;
        if (count > 0) {
            money = amount / count;
        }
        arpu = 0;
        if (user_count > 0) {
            arpu = amount / user_count;
        }
        cs = new ChargeStatis(amount, arpu, count, date, money, user_count, 1);
        this.chargeStatisService.addChargeStatis(cs);
    }

    private void updateNoActive() {
        SystemConfig config = this.systemConfigService.getSystemConfig();
        if (config.getNotActive() == -1) {
            return;
        }
        Calendar c = Calendar.getInstance();
        c.add(5, -config.getNotActive());
        String date = MyUtil.dateFormatYMD_Sting(c.getTime());
        this.userService.updateNoActive(date);
    }

}
